﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using DryIoc;
using TLDNs.Views;
using Prism.Commands;
using Prism.Events;
using Prism.Ioc;
using Prism.Mvvm;
using Prism.Regions;
using UsingEventAggregator.Core;
using ECANPort;
using Prism.Interactivity.InteractionRequest;
using System.Diagnostics;
using HCC = HandyControl.Controls;
using DataDefine;

namespace TLDNs.ViewModels
{

    public class MainWindowViewModel : MainCanDevViewModelBase
    {

        #region " MVVM 属性"
        private const int MaxLeftMenuWidth = 200;
        private const int MinLeftMenuWidth = 45;
        private int _LeftMenuOpenWidth = MaxLeftMenuWidth;
        public int LeftMenuOpenWidth
        {
            get { return _LeftMenuOpenWidth; }
            set { SetProperty(ref _LeftMenuOpenWidth, value); }
        }

        private bool _LeftMenuIsOpen = true;
        public bool LeftMenuIsOpen
        {
            get { return _LeftMenuIsOpen; }
            set
            {
                if (value)
                    LeftMenuOpenWidth = MaxLeftMenuWidth;
                else
                    LeftMenuOpenWidth = MinLeftMenuWidth;
                SetProperty(ref _LeftMenuIsOpen, value);
            }
        }

        private string _GloablMsg;
        public string GloablMsg
        {
            get { return _GloablMsg; }
            set
            {
                SetProperty(ref _GloablMsg, value);
            }
        }


        private AccessLv _CurUserAccessLv = AccessLv.User;
        public AccessLv CurUserAccessLv
        {
            get { return _CurUserAccessLv; }
            set
            {
                SetProperty(ref _CurUserAccessLv, value);
                Properties.Settings.Default.CurUserAccessLv = value;
            }
        }


        #endregion

        private static ulong _CanRecvCount;
        public ulong CanRecvCount
        {
            get { return _CanRecvCount; }
            set
            {
                SetProperty(ref _CanRecvCount, value);
                CanRecvWriteCount = $"R:{value} S:{CanWriteCount} SE:{CanSendErr}";
            }
        }

        private static ulong _CanWriteCount;
        public ulong CanWriteCount
        {
            get { return _CanWriteCount; }
            set
            {
                SetProperty(ref _CanWriteCount, value);
                CanRecvWriteCount = $"R:{CanRecvCount} S:{value} SE:{CanSendErr}";
            }
        }

        private static int _CanSendErr;
        public  int CanSendErr
        {
            get { return _CanSendErr; }
            set { SetProperty(ref _CanSendErr, value);
                CanRecvWriteCount = $"R:{CanRecvCount} S:{CanWriteCount} SE:{value}";
            }
        }

        private string _CanRecvWriteCount = "R:0 S:0 SE:0";
        public string CanRecvWriteCount
        {
            get { return _CanRecvWriteCount; }
            set { SetProperty(ref _CanRecvWriteCount, value); }
        }

        protected override void CanStatusChangeEventSub()
        {
            base.CanStatusChangeEventSub();
            Can1ErrMsg = "";
            Can2ErrMsg = "";
        }

        public MainWindowViewModel(IContainerExtension con, IRegionManager rm, IEventAggregator ea) : base(con, rm, ea)
        {
            RunParameter.ea = ea;
            ErrHisHelper._ea = ea;
            SelectCmd = new DelegateCommand<string>(SelectCmd_Sub);
            SwitchItemCmd = new DelegateCommand(SwitchItemCmd_Sub);
            WinClosingEvent = new DelegateCommand<Window>(WinClosingEvent_Sub);
            ChangeLeftMenuOpenStatusCommand = new DelegateCommand(ChangeLeftMenuOpenStatusCommand_Sub);
            //_ea.GetEvent<CanWriteCountChangeEvent>().Subscribe(() =>
            //{
            //    CanWriteCount++;
            //});
            _ea.GetEvent<CanRecvCountChangeEvent>().Subscribe(() =>
            {
                CanRecvCount++;
            });

            uint[] mCanIndex = GetIndex_FromDefaultSettings();
            CanDev = ECAN_Device.CreateDevice(mCanIndex);
            CanDev.CanSendErr += CanDev_CanSendErr;
            CanDev.CanSendOK += CanDev_CanSendOK;
            _ea.GetEvent<ChangeUIViewEvent>().Subscribe(SelectCmd_Sub);
            _ea.GetEvent<OpenSFMIsChangeEvent>().Subscribe(new Action(() =>
            {
                CanSave = true;
            }));
            _ea.GetEvent<SaveSFMOkEvent>().Subscribe(new Action(() =>
            {
                CanSave = false;
                SaveCount = SFMParameterIsChangeEvent.Count = 0;
                BadgeStatus = HandyControl.Data.BadgeStatus.Text;
            }));
            _ea.GetEvent<SFMParameterIsChangeEvent>().Subscribe(SFMParameterIsChangeEvent_Sub);

            _ea.GetEvent<GloablMsgEvent>().Subscribe(new Action<string>((msg) =>
            {
                GloablMsg = msg;
            }));

            INIT_CONFIG tmp;
            if (PubMod.Bin_deserializeStrToObj<INIT_CONFIG>(Properties.Settings.Default.DefaultCan1Config, out tmp))
            {
                Can1Config = tmp;
            }
            if (PubMod.Bin_deserializeStrToObj<INIT_CONFIG>(Properties.Settings.Default.DefaultCan2Config, out tmp))
            {
                Can2Config = tmp;
            }
            SystemInfoVisibility = Visibility.Visible;
            CurUserAccessLv = Properties.Settings.Default.CurUserAccessLv;
            _ea.GetEvent<GeneralSettingIsChangeEvent>().Subscribe(new Action<object>((obj) =>
            {
                GeneralSettingPar par = (GeneralSettingPar)obj;
                CurUserAccessLv = (AccessLv)par.UserAccessLv;

            }));
            OpenTestLog = Properties.Settings.Default.OpenTestLog;
            TestLog_Hz_S = Properties.Settings.Default.TestLog_Hz_S;
            if (TestLog_Hz_S < 600)
                TestLog_Hz_S = 600;
            if (OpenTestLog && TestLog == null)
            {
                TestLog = new Task(()=> {
                    while (true)
                    {
                        var sw = System.IO.File.AppendText("TestLog.log");
                        sw.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss.fff")}:{_CanRecvWriteCount}");
                        sw.Close();
                        Thread.Sleep(1000* TestLog_Hz_S);
                    }
                });
                
                TestLog.Start();
            }
        }

        private void CanDev_CanSendOK()
        {
            CanWriteCount++;
        }

        public static bool OpenTestLog = true;
        public static int TestLog_Hz_S = 60 * 10;
        private static Task TestLog;
        private void CanDev_CanSendErr()
        {
            CanSendErr++;
        }

        private void SFMParameterIsChangeEvent_Sub(decimal val)
        {
            CanSave = true;
            SaveCount = SFMParameterIsChangeEvent.Count;
            BadgeStatus = HandyControl.Data.BadgeStatus.Dot;
        }

        private void btnWrite_Click()
        {
            CAN_OBJ frameinfo;
            frameinfo = new CAN_OBJ();
            frameinfo.SendType = 0;
            frameinfo.data = new byte[8];
            frameinfo.Reserved = new byte[3];

            frameinfo.ID = Convert.ToUInt32("11", 16);
            frameinfo.DataLen = Convert.ToByte(8);
        }

        #region " Other Command"

        public DelegateCommand ChangeLeftMenuOpenStatusCommand { get; private set; }
        private void ChangeLeftMenuOpenStatusCommand_Sub()
        {
            LeftMenuIsOpen = !LeftMenuIsOpen;
        }

        private void SwitchItemCmd_Sub()
        {
            LeftMenuIsOpen = true;
        }
        Stopwatch sw = new Stopwatch();
        private void SelectCmd_Sub(string UCViewNameName)
        {
            sw.Restart();
            if (UCViewNameName != null)
            {
                if (UCViewNameName == "ParameterEdit")
                {
                    ParameterEditVisibility = Visibility.Visible;
                }
                if (UCViewNameName == "SystemInfo")
                {
                    SystemInfoVisibility = Visibility.Visible;
                }
                if (UCViewNameName == "ParameterExport")
                {
                    ParameterExportVisibility = Visibility.Visible;
                }
                if (UCViewNameName == "ParameterMonitoring")
                {
                    ParameterMonitoringVisibility = Visibility.Visible;
                }
                if (UCViewNameName == "ErrorHistory")
                {
                    ErrorHistoryVisibility = Visibility.Visible;
                }
                if (UCViewNameName == "SystemInfoGraph")
                {
                    SystemInfoGraphVisibility = Visibility.Visible;
                }
                if (UCViewNameName == "AppUpdate")
                {
                    AppUpdateVisibility = Visibility.Visible;
                }
                if (UCViewNameName == "TestFunctions")
                {
                    TestFunctionsVisibility = Visibility.Visible;
                }
                if (UCViewNameName == "ParameterEditTree")
                {
                    ParameterEditTreeVisibility = Visibility.Visible;
                }

            }
            sw.Stop();
            Console.WriteLine(UCViewNameName + "=>" + sw.ElapsedMilliseconds + "ms");
        }

        public DelegateCommand<string> SelectCmd { get; private set; }
        public DelegateCommand SwitchItemCmd { get; private set; }
        public DelegateCommand<Window> WinClosingEvent { get; private set; }
        private void WinClosingEvent_Sub(Window win)
        {
            CanDev.CloseCAN_Device();
            Properties.Settings.Default.MainRestoreBounds = win.RestoreBounds;
            Properties.Settings.Default.MianWinStatus = win.WindowState;
            Properties.Settings.Default.Save();
        }


        protected override void UILoadedCommand_Sub(ResourceDictionary obj)
        {
            base.UILoadedCommand_Sub(obj);

            try
            {
                ECANDLL.CloseDevice(1, 0);
                ECANDLL.ECANDLL_LoadOk = true;
            }
            catch (DllNotFoundException ex)
            {
                ECANDLL.ECANDLL_LoadOk = false;

                string DLLLib = (string)LangDic["DLLLib"];
                string Lost = (string)LangDic["Lost"];
                string CanModuleCantUse = (string)LangDic["CanModuleCantUse"];
                string DLLError = (string)LangDic["DLLError"];
                string msg = $"{DLLError}: {DLLLib}{ECANDLL.ECANDLL_NAME}{Lost}!,{CanModuleCantUse}";
                HCC.Growl.Warning(msg);
            }
            catch (Exception ex2)
            {
                ECANDLL.ECANDLL_LoadOk = false;
                string DLLLib = (string)LangDic["DLLLib"];
                string Lost = (string)LangDic["Lost"];
                string CanModuleCantUse = (string)LangDic["CanModuleCantUse"];
                string DLLError = (string)LangDic["DLLError"];
                string msg = $"{DLLError}: {DLLLib}{ECANDLL.ECANDLL_NAME} {ex2.Message}!,{CanModuleCantUse}";
                HCC.Growl.Warning(msg);
            }

        }
        #endregion

        #region  "UI Visibility"

        private void SetALLCollapsed()
        {
            SystemInfoVisibility = Visibility.Collapsed;
            ParameterEditVisibility = Visibility.Collapsed;
            ParameterExportVisibility = Visibility.Collapsed;
            ParameterMonitoringVisibility = Visibility.Collapsed;
            ErrorHistoryVisibility = Visibility.Collapsed;
            SystemInfoGraphVisibility = Visibility.Collapsed;
            AppUpdateVisibility = Visibility.Collapsed;
            TestFunctionsVisibility = Visibility.Collapsed;
            ParameterEditTreeVisibility = Visibility.Collapsed;
        }

        private Visibility _SystemInfoVisibility;
        public Visibility SystemInfoVisibility
        {
            get { return _SystemInfoVisibility; }
            set
            {
                SetProperty(ref _SystemInfoVisibility, value);
                if (value == Visibility.Visible)
                {
                    SetALLCollapsed();
                    SetProperty(ref _SystemInfoVisibility, value);
                }
            }
        }

        private Visibility _ParameterEditVisibility;
        public Visibility ParameterEditVisibility
        {
            get { return _ParameterEditVisibility; }
            set
            {
                SetProperty(ref _ParameterEditVisibility, value);
                if (value == Visibility.Visible)
                {
                    SetALLCollapsed();
                    SetProperty(ref _ParameterEditVisibility, value);
                }
            }
        }

        private Visibility _ParameterExportVisibility;
        public Visibility ParameterExportVisibility
        {
            get { return _ParameterExportVisibility; }
            set
            {
                SetProperty(ref _ParameterExportVisibility, value);
                if (value == Visibility.Visible)
                {
                    SetALLCollapsed();
                    SetProperty(ref _ParameterExportVisibility, value);
                }
            }
        }

        private Visibility _ParameterMonitoringVisibility;
        public Visibility ParameterMonitoringVisibility
        {
            get { return _ParameterMonitoringVisibility; }
            set
            {
                SetProperty(ref _ParameterMonitoringVisibility, value);
                if (value == Visibility.Visible)
                {
                    SetALLCollapsed();
                    SetProperty(ref _ParameterMonitoringVisibility, value);
                }
            }
        }

        private Visibility _ErrorHistoryVisibility;
        public Visibility ErrorHistoryVisibility
        {
            get { return _ErrorHistoryVisibility; }
            set
            {
                SetProperty(ref _ErrorHistoryVisibility, value);
                if (value == Visibility.Visible)
                {
                    SetALLCollapsed();
                    SetProperty(ref _ErrorHistoryVisibility, value);
                }
            }
        }

        private Visibility _SystemInfoGraphVisibility;
        public Visibility SystemInfoGraphVisibility
        {
            get { return _SystemInfoGraphVisibility; }
            set
            {
                SetProperty(ref _SystemInfoGraphVisibility, value);
                if (value == Visibility.Visible)
                {
                    SetALLCollapsed();
                    SetProperty(ref _SystemInfoGraphVisibility, value);
                }
            }
        }

        private Visibility _AppUpdateVisibility;
        public Visibility AppUpdateVisibility
        {
            get { return _AppUpdateVisibility; }
            set
            {
                SetProperty(ref _AppUpdateVisibility, value);
                if (value == Visibility.Visible)
                {
                    SetALLCollapsed();
                    SetProperty(ref _AppUpdateVisibility, value);
                }
            }
        }

        private Visibility _TestFunctionsVisibility;
        public Visibility TestFunctionsVisibility
        {
            get { return _TestFunctionsVisibility; }
            set
            {
                SetProperty(ref _TestFunctionsVisibility, value);
                if (value == Visibility.Visible)
                {
                    SetALLCollapsed();
                    SetProperty(ref _TestFunctionsVisibility, value);
                }
            }
        }

        private Visibility _ParameterEditTreeVisibility;
        public Visibility ParameterEditTreeVisibility
        {
            get { return _ParameterEditTreeVisibility; }
            set
            {
                SetProperty(ref _ParameterEditTreeVisibility, value);
                if (value == Visibility.Visible)
                {
                    SetALLCollapsed();
                    SetProperty(ref _ParameterEditTreeVisibility, value);
                }
            }
        }

        #endregion

        /// <summary>
        ///  Open SFM File
        /// </summary>    
        public DelegateCommand OpenSFMFileCommand => new DelegateCommand(OpenSFMFileCommand_Sub);
        private void OpenSFMFileCommand_Sub()
        {
            _ea.GetEvent<OpenSFMEvent>().Publish();
        }

        public DelegateCommand SaveSFMFileCommand => new DelegateCommand(SaveSFMFileCommand_Sub);
        private void SaveSFMFileCommand_Sub()
        {
            _ea.GetEvent<SaveSFMEvent>().Publish();
        }

        private bool _CanSave;
        public bool CanSave
        {
            get { return _CanSave; }
            set { SetProperty(ref _CanSave, value); }
        }
        private int _SaveCount;
        public int SaveCount
        {
            get { return _SaveCount; }
            set { SetProperty(ref _SaveCount, value); }
        }
        private HandyControl.Data.BadgeStatus _BadgeStatus = HandyControl.Data.BadgeStatus.Text;
        public HandyControl.Data.BadgeStatus BadgeStatus
        {
            get { return _BadgeStatus; }
            set { SetProperty(ref _BadgeStatus, value); }
        }


        public DelegateCommand RefreshCommand => new DelegateCommand(RefreshCommand_Sub);
        private void RefreshCommand_Sub()
        {
            Console.WriteLine("RefreshCommand");
            _ea.GetEvent<RefreshCanEvent>().Publish();
        }
        public DelegateCommand SyncInnerToUICommand => new DelegateCommand(SyncInnerToUICommand_Sub);
        private void SyncInnerToUICommand_Sub()
        {
            Console.WriteLine("SyncInnerToUICommand");
            _ea.GetEvent<SyncInnerToUIEvent>().Publish();
        }
        

        public DelegateCommand SaveToSystemCommand => new DelegateCommand(SaveToSystemCommand_Sub);
        private void SaveToSystemCommand_Sub()
        {
            Console.WriteLine("SaveToSystemCommand");
            _ea.GetEvent<SaveToCanSystemEvent>().Publish((Properties.Settings.Default.AutoSaveToInherSFM, Properties.Settings.Default.EqualWrite));
        }

        protected override void SFMFileIsReLoaded()
        {
            CanSave = true;
        }

        private int Ctrl_TCount = 0;
        private Task Ctrl_TTask;
        public DelegateCommand Ctrl_T_Command => new DelegateCommand(Ctrl_T_Command_sub);
        /// <summary>
        /// 快速按5次Ctrl+T 显示
        /// 慢速按两次Ctrl+T 关闭
        /// </summary>
        private void Ctrl_T_Command_sub()
        {
            Ctrl_TCount++;
            if (Ctrl_TTask == null)
            {
                Ctrl_TTask = new Task(() =>
                {
                    Thread.Sleep(3000);
                    if (Ctrl_TCount >= 5)
                    {
                        _ea.GetEvent<TestUIVisibilityEvent>().Publish(true);
                    }
                    else
                    {
                        _ea.GetEvent<TestUIVisibilityEvent>().Publish(false);
                    }
                });
                Ctrl_TTask.ContinueWith(new Action<Task>((t =>
                {  //任务完成后,处理尾巴
                    if (t.IsCompleted) // Ctrl_T Task
                    {
                        Ctrl_TCount = 0;
                        Ctrl_TTask = null;
                    }
                    else
                    {
                        Ctrl_TCount = 0;
                        Ctrl_TTask = null;
                    }
                })));

                Ctrl_TTask.Start();
            }
        }



    }
}
